
local show   = require "showmsg" 
local mysql  = require "skynet.db.mysql"
               require "strlib"

SQL_ERROR       = true 
SQL_SUCCESS     = false

local SQL = {}

function SQL:new_sql_handler()

    local Sql = {}
    Sql.db          = {}        -- 数据库句柄
    Sql.str         = ''        -- 查询语句
    Sql.result      = {}        -- 查询结果
    Sql.data        = ''        -- 获取数据
    Sql.dbname      = ''        -- 数据库名
   
    return Sql     
end 


--连接数据库
function SQL:connect_db(sql, conf, utf)

    if not sql or not conf then 
        return SQL_ERROR
    end 

    local function on_connect(db)
        db:query(utf or "set charset utf8")  --默认　字符集utf8
    end 

    local cfg = {}

    cfg.host             =     conf.host
    cfg.port             =     conf.port
    cfg.database         =     conf.basename
    cfg.user             =     conf.user
    cfg.password         =     conf.pawd
    cfg.max_packet_size  =     1024 * 1024
    cfg.on_connect       =     on_connect  

    sql.db = mysql.connect(cfg)

    if not sql.db then 

        show:SQL("mysql connect faild : host:%s\n  port:%s\n database:%s\n user:%s\n password:%s\n",conf.host,
            conf.port,conf.basename, conf.user, conf.pawd)
            
        return SQL_ERROR
    end 

    --保存数据库名　做断线重连　
    sql.dbname = conf.basename
   return SQL_SUCCESS
end 

--关闭数据库
function SQL:close_db(sql)

    if not sql  then 
        return SQL_ERROR
    end 

    sql.db:disconnect() 
    sql.str         = nil
    sql.result      = nil 
    sql.data        = nil 
    sql.db          = nil
    Sql.dbname      = nil 

    return SQL_SUCCESS
end 

--use 数据库
function SQL:ping(sql)

    if sql then 
        sql.db:query("use " .. sql.dbname)
    end    
end 

function SQL:free_result(sql)
    
    if sql then 

        sql.str         = ''
        sql.result      = {}
        sql.data        = ''     
    end 
end 

-- sql 句柄  query查询串  va_list 变长参数表 
function SQL:Vquery(sql, query, va_list)

    if not sql or not query or not va_list then   
        return SQL_ERROR
    end 

 
    self:free_result(sql)                       -- 查询之前先清空
    strbuf_Vformat(sql, query, va_list)         -- 格式化成字符串
    self:escape_string(sql)                     -- 转义字符                                    
    sql.result = sql.db:query(sql.str)          -- 执行sql语句

    if sql.result.err then 
    
        return SQL_ERROR
    end

    return SQL_SUCCESS     
end 

--  执行查询
function SQL:query(sql, format_str, ...)
    

    local va_list = {...}
    return  self:Vquery(sql, format_str, va_list)
end 


--返回最近插入的编号
function SQL:insert_id(sql, format_str, ...)

    local va_list = {...}
    return  self:Vquery(sql, format_str, va_list)
end
 
--[[
 返回一列集合里字段个数　　　　　　　　　　　{{}} sql ->　查询　回来的格式是数组
function SQL:num_columns(sql,index)

    if not sql or not sql.result or #sql.result==0 then 
        return SQL_ERROR, "Invalid argument"
    end  
  
  --  默认1  指定index 　不指定nil 三种情况
    local count = 0

    if index > 0  then  

        if M.sql_num_rows(sql) < index then 

            return SQL_ERR, "invalid index"
        else 

            for k,v in pairs(sql.result[index]) do 
                count = count + 1
            end

            return SQL_SUCCESS, count 
        end   
   end 

    --默认是获取[１]　因为lua数组下标从[１]开始，默认第一个值
    for k,v in pairs(sql.result[1]) do 
        count = count + 1
    end

    return SQL_SUCCESS,count
end 

]]--

--返回集合中的行数
function SQL:num_rows(sql)

    if not sql then 

        return SQL_ERROR
    end

    return #sql.result
end 

--获取数据(返回一个表)         col索引    
function SQL:get_data(sql, col)

    if not sql then 

        return SQL_ERROR
    end 
   
    if not col then  --默认返回[1]
     
        sql.data = sql.result[1]

    else 

        if col<=0 or  self:sql_num_rows(sql) < col then 
            sql.data = ''
            return SQL_ERROR
        end 

        -- 指定col获取 
        sql.data = sql.result[col] 
    end 
    
    return SQL_SUCCESS
end 

  
-- 转义 \''
function SQL:escape_string(sql)

    sql.str = string.gsub(sql.str, "'","\'")
end 

-- 显示调试信息
function SQL:show_debug(sql, debugFile, errInfo)

    if not sql then 
        show:debug("at %s:%s - sql is NULL", debugFile, errInfo)

    elseif sql.str then 
        show:debug("at %s:%s - %s", debugFile, errInfo, sql.str) 

    else 
        show:debug("at %s:%s", debugFile, errInfo) 
    end 
end

function SQL:accurate_query(tal_name, field, where, limit, sort)
end 

return SQL




